﻿using Cl.Entity.DataBaseEntity.User;
using Cl.Model.DataBaseEntityDtos.User.User;
using Cl.Model.Results;
using Cl.Repository;
using Cl.Utils;
using Cl.Utils.Helper.AutoMap;
using Cl.Utils.Helper.Compare;
using Cl.Utils.Helper.Encryption.SHA256;
using Microsoft.AspNetCore.Components.Forms;
using Newtonsoft.Json;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace Cl.Service.Service.User.Users
{
    public class UserServer : IUserServer
    {
        #region 依赖注入

        private ClRepository<Entity.DataBaseEntity.User.User> _userRepository;

        private ClRepository<UserHistory> _userHistoryRepository;

        private ClRepository<UserRole> _userRoleRepository;

        /// <summary>
        /// 构造函数
        /// </summary>
        public UserServer(ClRepository<Entity.DataBaseEntity.User.User> userRepository, ClRepository<UserRole> userRoleRepository, ClRepository<UserHistory> userHistoryRepository)
        {
            _userRepository = userRepository;
            _userRoleRepository = userRoleRepository;
            _userHistoryRepository = userHistoryRepository;
        }

        #endregion

        public UserOutDto FindUserInfo(int id)
        {
            UserOutDto result;
            var userInfo = _userRepository.AsQueryable().Where(x => x.Id == id)
                    .Includes(d => d.Department)
                    .Includes(d => d.CreateUser)
                    .Includes(d => d.UpdateUser)
                    .Includes(ur => ur.UserRoles, r => r.Role).First();
            if (userInfo == null)
                result = new UserOutDto();
            else
                result = new UserOutDto(userInfo);

            return result;// GetResult.Success("Success", result);
        }

        public PageResultModel<UserOutDto> QueryUserData(SearchUserDto request)
        {
            var response = new PageResultModel<UserOutDto>
            {
                Result = new List<UserOutDto>()
            };
            int totalCount = 0;

            var sql = _userRepository.AsQueryable()
                    .Includes(d => d.Department)
                    .Includes(d => d.CreateUser)
                    .Includes(d => d.UpdateUser)
                    .Includes(ur => ur.UserRoles, r => r.Role);

            if (!string.IsNullOrEmpty(request.Account))
            {
                sql.Where(p => p.Account.Contains(request.Account));
            }

            sql.OrderBy(p => p.Id, OrderByType.Desc);
            var data = sql.ToPageList(request.PageIndex, request.PageSize, ref totalCount)
                .Select(x => new UserOutDto(x) { }).ToList();
            response.TotalCount = totalCount;
            response.Result = data;
            return response;
        }


        public ResultInfoModel SaveUserData(UserInputDto inputDto)
        {
            try
            {
                _userRepository.BeginTran();

                //数据准备
                var operationData = inputDto.MapTo<UserInputDto, Entity.DataBaseEntity.User.User>();
                operationData.PassWord = CommonHelper.GetMD5Password(operationData.PassWord);
                List<UserRole> userRoles = new List<UserRole>();

                var _userId = _userRepository.AsInsertable(operationData).ExecuteReturnIdentity();
                foreach (var itemRoleId in inputDto.RoleIds)
                {
                    userRoles.Add(new UserRole() { CreateId = inputDto.CreateId, CreateTime = DateTime.Now, UserId = _userId, RoleId = itemRoleId });
                }
                _userRoleRepository.InsertRange(userRoles);

                _userRepository.CommitTran();


                return GetResult.Success("Success");
            }
            catch (Exception ex)
            {
                _userRepository.RollbackTran();
                return GetResult.Error(ex.Message);
            }




        }


        public ResultInfoModel UpdateUserData(UserInputDto inputDto)
        {
            try
            {
                if (inputDto.Id <= 0)
                    return GetResult.Error("找不到用户信息！");

                _userRepository.BeginTran();

                //用户操作记录
                var oldUser = FindUserInfo(inputDto.Id);

                //数据准备
                var operationData = inputDto.MapTo<UserInputDto, Entity.DataBaseEntity.User.User>();
                operationData.PassWord = CommonHelper.GetMD5Password(operationData.PassWord);
                List<UserRole> userRoles = new List<UserRole>();

                var updata = _userRepository.AsUpdateable(operationData).UpdateColumns(p => new
                {
                    p.Account,
                    p.PassWord,
                    p.UpdateId,
                    p.UpdateTime,
                    p.UserName,
                    p.DepartmentId,
                    p.IsEnable
                }).Where(p => p.Id == operationData.Id).ExecuteCommand() > 0;


                var currentRoleList = _userRoleRepository.AsQueryable().Where(x => x.UserId == operationData.Id).ToList();
                // 删除不再需要的用户角色关联
                var rolesToRemove = currentRoleList.Where(ur => !inputDto.RoleIds.Contains(ur.RoleId)).ToList();
                foreach (var role in rolesToRemove)
                {
                    _userRoleRepository.DeleteById(role.Id);
                }
                // 添加新的用户角色关联
                var rolesToAdd = inputDto.RoleIds.Except(currentRoleList.Select(ur => ur.RoleId)).ToList();
                foreach (var roleId in rolesToAdd)
                {
                    userRoles.Add(new UserRole() { CreateId = inputDto.CreateId, CreateTime = DateTime.Now, UserId = operationData.Id, RoleId = roleId });
                }
                _userRoleRepository.InsertRange(userRoles);



                var newUser = FindUserInfo(inputDto.Id);
                var changeTxt = CompareHelper.RecordDifferences(oldUser, newUser);
                if (!string.IsNullOrEmpty(changeTxt))
                {
                    UserHistory userHistory = new();
                    userHistory.UserId = operationData.Id;
                    userHistory.CreateId = inputDto.CreateId;
                    userHistory.CreateTime = DateTime.Now;
                    userHistory.OldValue = JsonConvert.SerializeObject(oldUser);
                    userHistory.NewValue = JsonConvert.SerializeObject(newUser);
                    userHistory.ChangesContext = changeTxt;
                    _userHistoryRepository.Insert(userHistory);
                }


                _userRepository.CommitTran();
                return GetResult.Success("Success");
            }
            catch (Exception ex)
            {
                _userRepository.RollbackTran();
                return GetResult.Error(ex.Message);
            }




        }


        public ResultInfoModel DeleteUserData(int userId)
        {
            try
            {
                _userRepository.BeginTran();

                if (userId <= 0)
                    return GetResult.Error("找不到用户信息！");

                var operationData = _userRepository.GetFirst(x => x.Id == userId);
                operationData.DeleteTime = DateTime.Now;
                var updata = _userRepository.AsUpdateable(operationData).UpdateColumns(p => new
                {
                    p.DeleteTime
                }).Where(p => p.Id == operationData.Id).ExecuteCommand() > 0;


                var currentRoleList = _userRoleRepository.AsQueryable().Where(x => x.UserId == userId).Select(x => x.Id).ToArray();
                foreach (var item in currentRoleList)
                {
                    var updateObj = new UserRole() { Id = item, DeleteTime = DateTime.Now }; //主键要有值
                    _userRoleRepository.AsUpdateable(updateObj).UpdateColumns(it => new { it.DeleteTime }).ExecuteCommand();
                    //_userRoleRepository.DeleteById(item);
                }

                UserHistory userHistory = new();
                userHistory.UserId = operationData.Id;
                userHistory.CreateId = GlobalUserManager.UserId;
                userHistory.CreateTime = DateTime.Now;
                userHistory.OldValue = "";
                userHistory.NewValue = "";
                userHistory.ChangesContext = "数据已删除;";
                _userHistoryRepository.Insert(userHistory);


                _userRepository.CommitTran();
                return GetResult.Success("Success");

            }
            catch (Exception ex)
            {

                _userRepository.RollbackTran();
                return GetResult.Error(ex.Message);
            }
        }



    }
}
